pub fn goldbach_conjecture() -> u64 {
    let mut iter=Goldbach::default().into_iter();
    iter.next().unwrap()+
        iter.next().unwrap()
}
struct Prime {
    prime: u64
}
impl Iterator for Prime{
    type Item = u64;

    fn next(&mut self) -> Option<Self::Item> {
        loop{
            let mut status: bool = true;
            if self.prime<=2{
                self.prime+=1;
                return Some(self.prime);
            }
            self.prime+=2;
            for i in (3..(self.prime as f64).sqrt() as u64 +1).step_by(2){
                if self.prime%i==0{
                    status=false;
                    break;
                }
            }
            if status{
                return Some(self.prime);
            }
        }
    }
}
impl Default for Prime {
    fn default() -> Self {
        Self{
            prime: 1
        }
    }
}
struct Goldbach {
    prime: Prime,
    primes:Vec<u64>,
    pows:Vec<u64>,
    start:u64
}
impl Iterator for Goldbach {
    type Item = u64;

    fn next(&mut self) -> Option<Self::Item> {
        let mut pow: u64 =self.pows.last().unwrap_or(&0u64).clone();
        let mut flag:bool;
        loop {
            self.start += 2;
            while self.primes.binary_search(&self.start).is_ok() {
                self.start += 2;
            }
            while self.start > pow {
                pow = (self.pows.len() as u64 + 1).pow(2) * 2;
                self.pows.push(pow);
            }
            while self.start*2 > self.primes.last().unwrap_or(&0u64).clone() {
                self.primes.push(self.prime.next().unwrap());
            }
            flag = false;
            for p in &self.pows {
                if self.start > p.clone() {
                    match self.primes.binary_search(&(self.start - p)) {
                        Ok(_) => {
                            flag = true;
                            break;
                        }
                        Err(_) => {

                        }
                    }
                }
                else {
                    break;
                }
            }
            if !flag {
                return Some(self.start);
            }
        }
    }
}
impl Default for Goldbach{
    fn default() -> Self {
        Self{
            prime: Prime::default(),
            primes: vec![],
            pows: vec![],
            start: 9
        }
    }
}
#[cfg(test)]
mod tests {
    use super::*;
    #[test]
    fn test_prime(){
        let mut prime = Prime::default();
        println!("{:?}", prime.next());
    }
    #[test]
    fn test_goldbach(){
        println!("{:?}", goldbach_conjecture());
    }
}